/*
 * Copyright (c) 2012 duowan.com. 
 * All Rights Reserved.
 * This program is the confidential and proprietary information of 
 * duowan. ("Confidential Information").  You shall not disclose such
 * Confidential Information and shall use it only in accordance with
 * the terms of the license agreement you entered into with duowan.com.
 */
package com.superhelper.deliver.task;

import java.util.Collections;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import com.superhelper.common.Consts;
import com.superhelper.common.domain.Task;
import com.superhelper.common.mapper.TaskMapper;
import com.superhelper.deliver.task.impl.AddTipTask;
import com.superhelper.deliver.task.impl.DeliverRecordTask;

/**
 * @author duanshao
 * 
 */
public class TaskDispatcher implements ApplicationContextAware {
    // default thread pool, can be injected
    private TaskThreadPool defaultTaskThreadPool;

    // thread pool's mapping
    private Map<String, TaskThreadPool> poolMapping;

    private static final String DEFAULT_POOL_NAME = "task.thread.pool.default";

    private ApplicationContext appContext;

    @Autowired
    private TaskMapper taskMapper;

    public void doService(Task task) {
        TaskThreadPool ttp = getAppropriatePool(task);

        if (StringUtils.equalsIgnoreCase(task.getType(), Consts.Task.deliver_record)) {
            ttp.execute(new DeliverRecordTask(appContext, taskMapper, task));
        } else if (StringUtils.equalsIgnoreCase(task.getType(), Consts.Task.add_tip)) {
            ttp.execute(new AddTipTask(appContext, taskMapper, task));
        } else if (StringUtils.equalsIgnoreCase(task.getType(), Consts.Task.query_deliver_record)) {
            ttp.execute(new DeliverRecordQueryTask(appContext, taskMapper, task));
        }
    }

    /*
     * 获取合适的任务线程池
     */
    private TaskThreadPool getAppropriatePool(Task task) {
        String pattern = task.getType();
        TaskThreadPool ttp = poolMapping.get(pattern.toLowerCase());
        if (ttp == null) {
            pattern = task.getType();
            ttp = poolMapping.get(pattern.toLowerCase());
        }
        if (ttp == null) {
            pattern = StringUtils.EMPTY;
            ttp = defaultTaskThreadPool;
        }
        return ttp;
    }

    public void setDefaultTaskThreadPool(TaskThreadPool defaultTaskThreadPool) {
        this.defaultTaskThreadPool = defaultTaskThreadPool;
    }

    public void setPoolMapping(Map<String, TaskThreadPool> poolMapping) {
        this.poolMapping = poolMapping;
    }

    public void setTaskMapper(TaskMapper taskMapper) {
        this.taskMapper = taskMapper;
    }

    public void init() {
        if (defaultTaskThreadPool == null) {
            defaultTaskThreadPool = new TaskThreadPool(20, DEFAULT_POOL_NAME);
        }
        if (poolMapping == null) {
            poolMapping = Collections.emptyMap();
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.appContext = applicationContext;
    }

}
